package com.it.common.utils

import android.content.Context
import android.net.ConnectivityManager
import android.os.Build
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.DataOutputStream
import java.io.InputStreamReader
import java.net.*
import java.util.*


/**
 *  @Description：
 *  @author：weishixiong
 *  @date：2023-05-08 15:11
 *
 */
object NetworkUtils {
    const val TAG = "NetworkManager"
    fun getGateway(): String? {
        try {
            val interfaces: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()
            while (interfaces.hasMoreElements()) {
                val networkInterface: NetworkInterface = interfaces.nextElement()
                val addresses = networkInterface.interfaceAddresses
                for (addr in addresses) {
                    val inetAddress: InetAddress = addr.address
                    if (!inetAddress.isLinkLocalAddress && !inetAddress.isLoopbackAddress && inetAddress is java.net.Inet4Address) {
                        val broadcast = addr.broadcast
                        if (broadcast != null) {
                            return inetAddress.hostAddress
                        }
                    }
                }
            }
        } catch (e: SocketException) {
            e.printStackTrace()
        }
        return null
    }

    fun getIpAddrMaskForInterfaces(interfaceName: String): String? {
        try {
            val networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces() //获取本机所有的网络接口
            while (networkInterfaceEnumeration.hasMoreElements()) { //判断 Enumeration 对象中是否还有数据
                val networkInterface =
                    networkInterfaceEnumeration.nextElement() //获取 Enumeration 对象中的下一个数据
                if (!networkInterface.isUp && interfaceName != networkInterface.displayName) { //判断网口是否在使用，判断是否时我们获取的网口
                    continue
                }
                for (interfaceAddress in networkInterface.interfaceAddresses) {    //
                    if (interfaceAddress.address is Inet4Address) {    //仅仅处理ipv4
                        return calcMaskByPrefixLength(interfaceAddress.networkPrefixLength.toInt()) //获取掩码位数，通过 calcMaskByPrefixLength 转换为字符串
                    }
                }
            }
        } catch (e: SocketException) {
            e.printStackTrace()
        }
        return "error"
    }

    //通过子网掩码的位数计算子网掩码
    fun calcMaskByPrefixLength(length: Int): String? {
        val mask = -0x1 shl 32 - length
        val partsNum = 4
        val bitsOfPart = 8
        val maskParts = IntArray(partsNum)
        val selector = 0x000000ff
        for (i in maskParts.indices) {
            val pos = maskParts.size - 1 - i
            maskParts[pos] = mask shr i * bitsOfPart and selector
        }
        var result = ""
        result = result + maskParts[0]
        for (i in 1 until maskParts.size) {
            result = result + "." + maskParts[i]
        }
        return result
    }

    fun getIpAddrForInterfaces(interfaceName: String): String? {
        try {
            val enNetworkInterface = NetworkInterface.getNetworkInterfaces() //获取本机所有的网络接口
            while (enNetworkInterface.hasMoreElements()) {  //判断 Enumeration 对象中是否还有数据
                val networkInterface = enNetworkInterface.nextElement() //获取 Enumeration 对象中的下一个数据
                if (!networkInterface.isUp) { // 判断网口是否在使用
                    continue
                }
                if (interfaceName != networkInterface.displayName) { // 网口名称是否和需要的相同
                    continue
                }
                val enInetAddress =
                    networkInterface.inetAddresses //getInetAddresses 方法返回绑定到该网卡的所有的 IP 地址。
                while (enInetAddress.hasMoreElements()) {
                    val inetAddress = enInetAddress.nextElement()
                    if (inetAddress is Inet4Address) {  //判断是否未ipv4
                        return inetAddress.hostAddress
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return "error"
    }


    suspend fun setEthernetIpAddress(ipAddress: String, netmask: String, gateway: String) =
        withContext(Dispatchers.IO) {

            try {
                LogUtil.d(
                    TAG,
                    "setEthernetIpAddress ipAddress = ${ipAddress} and netmask = ${netmask} and gateway = ${gateway}"
                )
                // 获取 root 权限
                val suProcess = Runtime.getRuntime().exec("su")
                val outputStream = DataOutputStream(suProcess.outputStream)

                // 设置 IP 地址
                val setIPAddressCommand = """${"ifconfig eth0 $ipAddress"} up"""
                outputStream.writeBytes(setIPAddressCommand)
                outputStream.flush()

//            // 设置网关
//            val setGatewayCommand = """${"route add default gw $gateway"} dev eth0"""
//            outputStream.writeBytes(setGatewayCommand)
//            outputStream.flush()

                // 关闭输出流和进程
                outputStream.close()
                suProcess.waitFor()
            } catch (e: Exception) {
                LogUtil.d(TAG, "setEthernetIpAddress e ${e.message}")
            }


        }

    fun getEthernetIpAddress(): String {
        var address = ""
        try {
            val interfaces = NetworkInterface.getNetworkInterfaces()
            while (interfaces.hasMoreElements()) {
                val networkInterface = interfaces.nextElement()
                if (networkInterface.isUp && networkInterface.name == "eth0") {
                    val addresses = networkInterface.inetAddresses
                    while (addresses.hasMoreElements()) {
                        val inetAddress = addresses.nextElement()
                        if (!inetAddress.isLinkLocalAddress && inetAddress is Inet4Address) {
                            address = inetAddress.toString().substring(1)
                            break
                        }
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return address
    }

    /**
     * 使用adb shell命令来获取网关IP
     * @return
     */
    fun getGatewayIp(): String {
        var result = ""
        val order = "ip route list table 0"

        try {
            val exec = Runtime.getRuntime().exec(order)
            val buff = BufferedReader(InputStreamReader(exec.inputStream))

            val str = buff.readLine()
            if (str != null) {
                result = str.trim().split("\\s+".toRegex()).toTypedArray()[2]
            }

            buff.close()
            exec.waitFor()
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return result
    }

    /**
     * @return 获取所有有效的网卡
     */
    fun getAllNetInterface(): Array<String?>? {
        val availableInterface: ArrayList<String> = ArrayList()
        var interfaces: Array<String?>? = null
        try {
            //获取本地设备的所有网络接口
            val nis = NetworkInterface.getNetworkInterfaces()
            var ia: InetAddress? = null
            while (nis.hasMoreElements()) {
                val ni = nis.nextElement() as NetworkInterface
                val ias = ni.inetAddresses
                while (ias.hasMoreElements()) {
                    ia = ias.nextElement()
                    if (ia is Inet6Address) {
                        continue  // skip ipv6
                    }
                    val ip = ia.hostAddress
                    // 过滤掉127段的ip地址
                    if ("127.0.0.1" != ip) {
                        if (ni.name.substring(0, 3) == "eth") { //筛选出以太网
                            availableInterface.add(ni.name)
                        }
                    }
                }
            }
        } catch (e: SocketException) {
            e.printStackTrace()
        }
        val size: Int = availableInterface.size
        if (size > 0) {
            interfaces = arrayOfNulls(size)
            for (i in 0 until size) {
                interfaces[i] = availableInterface[i]
            }
        }
        return interfaces
    }


    fun getGatewayAddress(context: Context): String? {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            if (cm != null) {
                val network = cm.activeNetwork
                if (network != null) {
                    val linkProperties = cm.getLinkProperties(network)
                    if (linkProperties != null) {
                        for (route in linkProperties.routes) {
                            if (route.isDefaultRoute) {
                                return route.gateway!!.getHostAddress()
                            }
                        }
                    }
                }
            }
        }
        return null
    }

    fun isNetworkAvailable(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (connectivityManager != null) {
            val activeNetworkInfo = connectivityManager.activeNetworkInfo
            return activeNetworkInfo != null && activeNetworkInfo.isConnected
        }
        return false
    }


}